package cn.yxm.recsys.online.controller;

import cn.yxm.recsys.online.dto.GenreDto;
import cn.yxm.recsys.online.dto.GenreMovieDto;
import cn.yxm.recsys.online.dto.MovieDto;
import cn.yxm.recsys.online.dto.UserDto;
import cn.yxm.recsys.online.entity.Movie;
import cn.yxm.recsys.online.entity.User;
import cn.yxm.recsys.online.service.GenreService;
import cn.yxm.recsys.online.service.MovieService;
import cn.yxm.recsys.online.service.RecService;
import cn.yxm.recsys.online.service.UserService;
import cn.yxm.recsys.online.vo.MovieVo;
import cn.yxm.recsys.online.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import cn.yxm.recsys.online.util.ResponseResult;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/rec")
public class RecController {

    @Autowired
    private UserService userService;

    @Autowired
    private MovieService movieService;

    @Autowired
    private GenreService genreService;

    @Autowired
    private RecService recService;

    /**
     * @return 各类别电影评分排序列表
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public ResponseResult index() {
        // 推荐系统主页结果
        Map<String, Object> resultMap = new HashMap<>();
        //1.构建示例用户列表，为简化，直接构建2个数据库内用户
        List<UserDto> users = new ArrayList<>();
        users.add(new UserDto(1, "user1"));
        users.add(new UserDto(2, "user2"));
        resultMap.put("users", users);

        //2.获取数据库内2个类别
        List<GenreDto> genres = genreService.getTwoGenre();
        //3.获取各类别下电影，按评分排序
        List<GenreMovieDto> genreMovies = new ArrayList<>();
        for (GenreDto genre : genres) {
            GenreMovieDto genreMovie = new GenreMovieDto();
            genreMovie.setId(genre.getId());
            genreMovie.setName(genre.getName());
            genreMovie.setMovieList(movieService.getMoviesByGenre(genre.getId(), 5));
            genreMovies.add(genreMovie);
        }
        resultMap.put("movies", genreMovies);

        return ResponseResult.ok(resultMap);
    }

    /**
     * @param movieId 电影id
     * @return 影片详情和相似影片别列表
     */
    @RequestMapping(value = "/movie", method = RequestMethod.GET)
    public ResponseResult movie(Integer movieId) {
        MovieVo result = new MovieVo();
        // 1.根据movieId拿到影片详情，mysql
        Movie movie = movieService.getMovie(movieId);
        BeanUtils.copyProperties(movie, result);
        // 2.获取给该影片打分最高的几个用户，mysql
        List<UserDto> users = userService.getTopScoreUser(movieId);
        result.setUsers(users);
        // 3.获取影片所属类型，mysql
        List<GenreDto> genres = genreService.getGenresByMovie(movieId);
        result.setGenres(genres);
        // 4.相似影片列表计算，得到列表内各影片id todo 未实现内容
        List<Integer> movieIds = recService.similarMovies(movieId);
        // 5.相似影片根据id，到mysql获取详情
        List<MovieDto> movies = movieService.getList(movieIds);
        result.setRelatedMovies(movies);
        return ResponseResult.ok(result);
    }

    /**
     * @param userId 用户id
     * @return 用户详情、推荐列表和观影历史
     */
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public ResponseResult user(Integer userId) {
        UserVo result = new UserVo();
        // 1.根据userId到mysql获取用户详情
        User user = userService.getUser(userId);
        BeanUtils.copyProperties(user, result);
        // 2.获取用户观看最多的电影类型，mysql todo
        result.setFavoriteGenre("action");
        result.setFavoriteGenreId(1);

        // 3.获取用户最近评分5部电影，mysql todo
        List<MovieDto> historyMovies = movieService.getMoviesByUser(userId, 5);
        result.setWatchedMovies(historyMovies);

        // 4.推荐服务，获取推荐电影列表 todo 未实现内容
        List<Integer> movieIds = recService.recForUser(userId);
        // 5.到mysql获取推荐类表详情
        List<MovieDto> movies = movieService.getList(movieIds);
        result.setRecMovieList(movies);

        return ResponseResult.ok(result);
    }

    /**
     * @param genreId 类别id
     * @return 该类别下影片列表，根据得分排序
     */
    @RequestMapping(value = "/genre", method = RequestMethod.GET)
    public ResponseResult genre(Integer genreId) {
        // 1.根据genreId到mysql获取影片列表
        List<MovieDto> movies = movieService.getMoviesByGenre(genreId, 10);
        return ResponseResult.ok(movies);
    }

}
